import { Injectable, Inject, ViewChild } from "@angular/core";
import { Router } from "@angular/router";
import { Actions, Effect, ofType } from "@ngrx/effects";
import { of } from "rxjs";
import { catchError, exhaustMap, tap, combineLatest } from "rxjs/operators";
import {
  ISelectSymbolResponse,
  ISelectSymbolRequest,
  IMu,
  IZi,
  IAddOrderRequest,
  IDelOrderRequest,
  ISelectOrderRequest,
  ISelectCoinListsRequest,
  ISelectActiveRequest,
  ISelectHistoryRequest
} from "@/trade/store/models/trade";

import { Store, select } from "@ngrx/store";
import * as fromTrade from "@/trade/store/reducers/index";
import { map, filter, skip, switchMap } from "rxjs/operators";
import { Subscription } from "rxjs";
import { UserActions } from "@/user/store/actions";
import { combineAll, debounceTime } from "rxjs/operators";
import { TradeActions } from "@/trade/store/actions";

import * as fromUser from "@/user/store/reducers/index";
import * as fromRoot from "@/reducers/index";
import { ActivatedRoute } from "@angular/router";

@Injectable()
export class TradeEffects {
  user$ = this.store.pipe(
    select(fromRoot.user),
    filter(user => !!user)
  );

  query: any;

  user: any;

  constructor(
    private actions$: Actions,
    @Inject("SymbolService") private symbolService,
    @Inject("MsgService") private msgService,
    @Inject("TradeService") private tradeService,
    @Inject("UserService") private userService,
    private router: Router,
    private store: Store<fromTrade.State | fromUser.State | fromRoot.State>,
    private activeRouter: ActivatedRoute
  ) {
    this.activeRouter.queryParams.subscribe(e => {
      this.query = e;
    });
    this.user$.subscribe(e => {
      this.user = e;
    });
  }

  @Effect()
  selectSymbol$ = this.actions$.pipe(
    ofType<TradeActions.SelectSymbol>(
      TradeActions.TradeActionTypes.SelectSymbol
    ),
    map(action => action.payload.req),
    exhaustMap((req: ISelectSymbolRequest) => {
      return this.symbolService.select(req).pipe(
        map((res: any) => {
          return new TradeActions.SelectSymbolSuccess({ res });
        }),
        catchError(error => of(new TradeActions.SelectSymbolError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  selectSymbolSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectSymbolSuccess),
    tap((response: any) => {
      const { payload } = response;
      // if (200 === payload.res.code) {
      //   this.msgService.success("success");
      // } else {
      //   this.msgService.error("error");
      // }
    })
  );

  @Effect({ dispatch: false })
  selectSymbolError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectSymbolError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  addOrder$ = this.actions$.pipe(
    ofType<TradeActions.AddOrder>(TradeActions.TradeActionTypes.AddOrder),
    map(action => action.payload.req),
    exhaustMap((req: IAddOrderRequest) => {
      return this.tradeService.addOrder(req).pipe(
        map((res: any) => {
          return new TradeActions.AddOrderSuccess({ res });
        }),
        catchError(error => of(new TradeActions.AddOrderError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  addOrderSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.AddOrderSuccess),
    tap((response: any) => {
      const { payload } = response;
      if (200 === payload.res.code) {
        this.msgService.success("success");

        const [zi, mu] = this.query.symbol.split("_");

        // this.store.dispatch(
        //   new TradeActions.SelectOrder({ req: { uid: this.user.id, zi, mu } })
        // );
      } else {
        this.msgService.error("error");
      }
    })
  );

  @Effect({ dispatch: false })
  addOrderError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.AddOrderError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  selectOrder$ = this.actions$.pipe(
    ofType<TradeActions.SelectOrder>(TradeActions.TradeActionTypes.SelectOrder),
    map(action => action.payload.req),
    exhaustMap((req: ISelectOrderRequest) => {
      return this.tradeService.selectOrder(req).pipe(
        map((res: any) => {
          return new TradeActions.SelectOrderSuccess({ res });
        }),
        catchError(error => of(new TradeActions.SelectOrderError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  selectOrderSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectOrderSuccess),
    tap((response: any) => {
      const { payload } = response;

      // if (200 === payload.res.code) {
      //   this.msgService.success("success");
      // } else {
      //   this.msgService.error("error");
      // }
    })
  );

  @Effect({ dispatch: false })
  selectOrderError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectOrderError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  selectActive$ = this.actions$.pipe(
    ofType<TradeActions.SelectActive>(
      TradeActions.TradeActionTypes.SelectActive
    ),
    map(action => action.payload.req),
    exhaustMap((req: ISelectActiveRequest) => {
      return this.tradeService.selectActive(req).pipe(
        map((res: any) => {
          return new TradeActions.SelectActiveSuccess({ res });
        }),
        catchError(error => of(new TradeActions.SelectActiveError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  selectActiveSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectActiveSuccess),
    tap((response: any) => {
      const { payload } = response;

      // if (200 === payload.res.code) {
      //   this.msgService.success("success");
      // } else {
      //   this.msgService.error("error");
      // }
    })
  );

  @Effect({ dispatch: false })
  selectActiveError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectActiveError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  selectHistory$ = this.actions$.pipe(
    ofType<TradeActions.SelectHistory>(
      TradeActions.TradeActionTypes.SelectHistory
    ),
    map(action => action.payload.req),
    exhaustMap((req: ISelectHistoryRequest) => {
      return this.tradeService.selectHistory(req).pipe(
        map((res: any) => {
          return new TradeActions.SelectHistorySuccess({ res });
        }),
        catchError(error => of(new TradeActions.SelectHistoryError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  selectHistorySuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectHistorySuccess),
    tap((response: any) => {
      const { payload } = response;
      // if (200 === payload.res.code) {
      //   this.msgService.success("success");
      // } else {
      //   this.msgService.error("error");
      // }
    })
  );

  @Effect({ dispatch: false })
  selectHistoryError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectHistoryError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  delOrder$ = this.actions$.pipe(
    ofType<TradeActions.DelOrder>(TradeActions.TradeActionTypes.DelOrder),
    map(action => action.payload.req),
    exhaustMap((req: IDelOrderRequest) => {
      return this.tradeService.delOrder(req).pipe(
        map((res: any) => {
          return new TradeActions.DelOrderSuccess({ res });
        }),
        catchError(error => of(new TradeActions.DelOrderError({ error })))
      );
    })
  );

  @Effect({ dispatch: false })
  delOrderSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.DelOrderSuccess),
    tap((response: any) => {
      const { payload } = response;
      if (200 === payload.res.code) {
        const [zi, mu] = this.query.symbol.split("_");
        // this.store.dispatch(
        //   new TradeActions.SelectOrder({ req: { uid: this.user.id, zi, mu } })
        // );
        this.msgService.success("success");
      } else {
        this.msgService.error("error");
      }
    })
  );

  @Effect({ dispatch: false })
  delOrderError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.DelOrderError),
    tap(() => {
      this.msgService.error("error");
    })
  );

  @Effect()
  selectCoinLists$ = this.actions$.pipe(
    ofType<TradeActions.SelectCoinLists>(
      TradeActions.TradeActionTypes.SelectCoinLists
    ),
    map(action => action.payload.req),
    exhaustMap((req: ISelectCoinListsRequest) => {
      return this.tradeService.selectCoinLists(req).pipe(
        map((res: any) => {
          return new TradeActions.SelectCoinListsSuccess({ res });
        }),
        catchError(error =>
          of(new TradeActions.SelectCoinListsError({ error }))
        )
      );
    })
  );

  @Effect({ dispatch: false })
  selectCoinListsSuccess$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectCoinListsSuccess),
    tap((response: any) => {
      const { payload } = response;
      // if (200 === payload.res.code) {
      //   this.msgService.success("success");
      // } else {
      //   this.msgService.error("error");
      // }
    })
  );

  @Effect({ dispatch: false })
  selectCoinListsError$ = this.actions$.pipe(
    ofType(TradeActions.TradeActionTypes.SelectCoinListsError),
    tap(() => {
      this.msgService.error("error");
    })
  );
}
